#include "RenderVisitor.h"
#include "Camera.h"

RenderVisitor::RenderVisitor( Camera* c )
{
	m_Camera = c;
}

void RenderVisitor::visit( AbstractEntity* ent )
{
	ent->accept(this);
}

void RenderVisitor::visit( EntityGroup* entity )
{
	//is het object wel in het frustum?
	if(!m_Camera->isBoundingBoxInFrustum( entity->getAbsolutePosition(), entity->getBoundingSize() ))
		return;

	if(m_Camera->getMovementMap().showBounding)
		m_Camera->drawBoundingBox( entity);

	m_entitiesVisited++;

	std::vector<AbstractEntity*>::const_iterator it;
	for( it = entity->getChildren().begin(); it != entity->getChildren().end(); it++ )
	{
		(*it)->accept(this);
	}
}

void RenderVisitor::visit( Entity* entity )
{
	//is het object wel in het frustum?
	if(!m_Camera->isBoundingBoxInFrustum( entity->getAbsolutePosition(), entity->getBoundingSize() ))
		return;

	if(m_Camera->getMovementMap().showBounding)
		m_Camera->drawBoundingBox( entity);

	m_entitiesVisited++;

	// Draw entity itself
	Texture& tex = entity->getTexture();
	const Color& col = entity->getColor();
	glColorMaterial ( GL_FRONT_AND_BACK, GL_EMISSION ) ;
	glEnable(GL_COLOR_MATERIAL);
	glColor3f( col.red, col.green, col.blue );

	switch( entity->getShape()->getType() )
	{
	case Shape::SPHERE:
		{
			glPushMatrix();
			const Position& p = (*entity->getPoints().begin());
			glTranslatef(p.x, p.y, p.z);

			GLUquadricObj* sphere_quad = gluNewQuadric() ;
			gluSphere( sphere_quad, 5.0f, entity->getBoundingSize().x, 10 ) ;

			glPopMatrix();
			break;
		}
	case Shape::CUBE:
		{		
			if( tex.isValid() )
				tex.bind();

			glBegin(GL_TRIANGLES);

			const std::vector<Position>& points = entity->getPoints();
			const std::vector<std::pair<int, int>> textureCoords = dynamic_cast<Cube*>(entity->getShape())->getTextureCoords();

			std::vector<Position>::const_iterator it2;
			int i = 0;
			for( it2 = points.begin(); it2 != points.end(); it2++ )
			{
				const Position& p = *it2;

				if( tex.isValid() )
					glTexCoord2d(textureCoords[i].first, textureCoords[i].second);

				glVertex3f( p.x, p.y, p.z );

				i++;
			}

			glEnd();

			// Draw zwarte lintjes om object heen, debugging
			glColor3f(0, 0, 0);
			glBegin(GL_LINE_LOOP);

			for( it2 = points.begin(); it2 != points.end(); it2++ )
			{
				const Position& p = *it2;
				glVertex3f( p.x, p.y, p.z );
			}

			glEnd();

			if( tex.isValid() )
				tex.unbind();
		}
	}

	if( m_Camera->getMovementMap().showNormals )
		m_Camera->drawNormals( entity );
}